import { ArrowRightOutlined, EnvironmentOutlined } from "@ant-design/icons";
import { Modal, Select, Table, message } from "antd";
import SearchPng from "@/assets/images/search.png";
import { useEffect, useLayoutEffect, useRef, useState } from "react";
import { Button, Spin } from "antd";
import { SaveOutlined } from "@ant-design/icons";
import { downloadFile, post } from "@/request";
import { useLocation } from "react-router";

declare const fornac: any;

export default function Search() {
  const [dataSource, setDataSource] = useState<any>([]);
  const [options, setOptions] = useState<any>([]);
  const [value, setValue] = useState<any>("");
  const [loading, setLoading] = useState(false);
  const tableRef = useRef(null);
  const [open, setOpen] = useState(false);
  const [info, setInfo] = useState({
    dotBracketNotation: "",
    substrateSeq: "",
    ribozymeSeq: "",
  });
  const [keyword, setKeyword] = useState("");
  const location: any = useLocation();
  const [total, setTotal] = useState(0);
  const [current, setCurrent] = useState(1);
  const [pageSize, setPageSize] = useState(10);
  const isSpecies = useRef("");
  const searchName = useRef("");
  const [messageApi, contextHolder] = message.useMessage();
  const [spinning, setSpinning] = useState(false);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);

  const columns = [
    {
      title: "Ribozyme",
      dataIndex: "ribozyme",
      key: "ribozyme",
      width: 120,
      fixed: "left",
      sorter: true,
    },
    {
      title: (
        <div>
          k<sub>obs</sub>(min<sup>-1</sup>)
        </div>
      ),
      dataIndex: "kobs",
      key: "kobs",
      width: 120,
      sorter: true,
    },
    {
      title: (
        <div>
          K<sub>m</sub>(μm)
        </div>
      ),
      dataIndex: "km",
      key: "km",
      width: 120,
      sorter: true,
    },
    {
      title: (
        <div>
          K<sub>cat</sub>(min<sup>-1</sup>)
        </div>
      ),
      dataIndex: "kcat",
      key: "kcat",
      width: 120,
      sorter: true,
    },
    {
      title: (
        <div>
          K<sub>cat</sub>/K<sub>m</sub>(μM<sup>-1</sup>·min<sup>-1</sup>)
        </div>
      ),
      dataIndex: "kcatKm",
      key: "kcatKm",
      width: 200,
      sorter: true,
    },
    {
      title: "Temperature °C",
      dataIndex: "commentaryTemp",
      key: "commentaryTemp",
      width: 160,
      sorter: true,
    },
    {
      title: "pH",
      dataIndex: "commentaryPh",
      key: "commentaryPh",
      width: 160,
      sorter: true,
    },
    {
      title: "Mutation",
      dataIndex: "commentaryMutant",
      key: "commentaryMutant",
      width: 160,
      sorter: true,
    },
    {
      title: "Mutation type",
      dataIndex: "mutationType",
      key: "mutationType",
      width: 180,
      sorter: true,
    },
    {
      title: "Metal ions",
      dataIndex: "commentaryOthers",
      key: "commentaryOthers",
      width: 160,
      sorter: true,
    },
    {
      title: "Pubmed ID",
      dataIndex: "pubmedid",
      key: "pubmedid",
      width: 160,
      sorter: true,
    },
    {
      title: "Ribozyme sequence",
      dataIndex: "ribozymeSeq",
      key: "ribozymeSeq",
      width: 120,
      sorter: true,
    },
    {
      title: "Substrate sequence",
      dataIndex: "substrateSeq",
      key: "substrateSeq",
      width: 120,
      sorter: true,
    },
    {
      title: "Annotation",
      dataIndex: "annotation",
      key: "annotation",
      width: 200,
      sorter: true,
    },
    {
      title: "Dot-bracket notation",
      dataIndex: "dotBracketNotation",
      key: "dotBracketNotation",
      width: 200,
    },
  ];
  const sortParams: any = {
    ribozyme: null,
    kobs: null,
    km: null,
    kcat: null,
    kcatKm: null,
    commentaryTemp: null,
    commentaryPh: null,
    commentaryMutant: null,
    commentaryOthers: null,
    pubmedid: null,
    ribozymeSeq: null,
    substrateSeq: null,
    annotation: null,
  };

  const getOptions = (name?: string) => {
    post("/function/getRibozymeSearchType").then((res: any) => {
      !value1.current ? setValue(res[0].id) : setValue(Number(value1.current));
      setOptions([...res].map((item) => ({ value: item.id, label: item.fieldName })));
      getDataList(name, value1.current || res[0].id);
    });
  };

  const handleChange = (value: string) => {
    setValue(value);
  };

  const getDataList = (name?: string, id?: number, current1?: number, pageSize1?: number) => {
    setLoading(true);
    post("/function/getRibozymeDataList", {
      isSpecies: isSpecies.current,
      isPage: 1,
      pageStartIndex: current1 || current,
      pageSizeIndex: pageSize1 || pageSize,
      searchName: name || keyword,
      searchField: id || value,
      sortParams,
    })
      .then((res: any) => {
        setDataSource([...res.vos.map((item: any) => ({ ...item, key: item.id }))]);
        setTotal(res.total);
      })
      .finally(() => {
        setLoading(false);
      });
  };

  const handleOk = () => {
    setOpen(false);
  };

  const initForanc = () => {
    dataSource.forEach((item: any) => {
      try {
        const dom = document.getElementById(`2d-structure${item.id}`);
        var container = new fornac.FornaContainer(dom, {
          zoomable: true,
          animation: false,
          editable: true,
          initialSize: [100, 30],
          layout: "naview",
        });
        var options = {
          structure: item.dotBracketNotation,
          sequence: item.ribozymeSeq + "&" + item.substrateSeq,
        };
        container.addRNA(options.structure, options);
      } catch (e) {
        console.log(item);
      }
    });
    window.scrollTo({ top: 0 });
  };

  const showModel = (id: string) => {
    const value = dataSource.find((item: any) => item.id === id);
    setOpen(true);
    setInfo({
      dotBracketNotation: value.dotBracketNotation,
      substrateSeq: value.substrateSeq,
      ribozymeSeq: value.ribozymeSeq,
    });
  };

  const useQuery = () => {
    return new URLSearchParams(location.search);
  };

  const handleChange1 = (current: any) => {};

  const exportFile = () => {
    setSpinning(true);
    downloadFile("function/exportRibozymeData", {}, "table.xlsx").finally(() => {
      setSpinning(false);
    });
  };
  const exportFile1 = () => {
    if (!selectedRowKeys.length) {
      return messageApi.open({
        type: "error",
        content: "请选择列",
      });
    }
    setSpinning(true);
    downloadFile(
      "function/exportRibozymeData",
      {
        isSpecies: isSpecies.current,
        isPage: current,
        pageStartIndex: current,
        pageSizeIndex: 10,
        searchName: keyword,
        searchField: value,
        sortParams,
        exportIds: selectedRowKeys.map((item) => Number(item)).join(","),
      },
      "table.xlsx"
    ).finally(() => {
      setSpinning(false);
    });
  };

  const sortChange = (pagination: any, filters: any, sorter: any) => {
    setCurrent(pagination.current);
    setPageSize(pagination.pageSize);
    setSelectedRowKeys([]);
    for (let key in sortParams) {
      sortParams[key] = 2;
    }
    const { columnKey, field, order } = sorter;
    if (columnKey) {
      sortParams[columnKey] = order === "ascend" ? 1 : 0;
    }
    getDataList("", 0, pagination.current, pagination.pageSize);
  };

  const rowSelection = {
    onChange: (selectedRowKeys1: any, selectedRows: any[]) => {
      setSelectedRowKeys(selectedRows.map((item) => item.id));
    },
    getCheckboxProps: (record: any) => ({
      name: record.id,
    }),
    selectedRowKeys: selectedRowKeys,
  };

  const value1 = useRef("");

  useEffect(() => {
    const query: any = useQuery();
    isSpecies.current = query.get("isSpecies");
    searchName.current = query.get("name");
    value1.current = query.get("value");
    // setValue(query.get("value"));
    setKeyword(searchName.current);
    getOptions(searchName.current);
  }, []);

  useLayoutEffect(() => {
    initForanc();
  }, [dataSource]);

  useLayoutEffect(() => {
    try {
      var container = new fornac.FornaContainer("#cofold_ss", {
        zoomable: true,
        animation: false,
        initialSize: [600, 800],
        layout: "naview",
      });
      var options = {
        structure: info.dotBracketNotation,
        sequence: info.ribozymeSeq + "&" + info.substrateSeq,
      };
      container.addRNA(options.structure, options);
    } catch (e) {
      console.log("cuowu1");
    }
  }, [info]);

  return (
    <div>
      {contextHolder}
      <Spin spinning={spinning} fullscreen tip="下载中..." size="large" />
      <div
        style={{
          maxWidth: "1200px",
          background: "#fff",
          margin: "20px auto",
          display: "flex",
          gap: "10px",
          padding: "20px",
        }}
      >
        <div style={{ color: "#459af1", cursor: "pointer" }}>
          <EnvironmentOutlined />
          <span style={{ marginLeft: "10px" }}>Home</span>
        </div>
        <div>
          <ArrowRightOutlined />
        </div>
        <div>Search</div>
      </div>
      <div style={{ width: "100%", background: "#fff", padding: "20px", boxSizing: "border-box" }}>
        <div style={{ maxWidth: "1200px", margin: "0 auto" }}>
          <div style={{ fontSize: "20px", fontWeight: "700" }}>
            List of kinetic data associated with the keyword "{keyword}": {total} items
          </div>
          <div style={{ marginTop: "20px" }} className="tableText1">
            Search the table:
          </div>
          <div
            className="search1"
            style={{ display: "flex", alignItems: "center", maxWidth: "1000px", marginTop: "20px" }}
          >
            <div style={{ marginRight: "20px" }} className="tableText">
              Search the table:
            </div>
            <div
              style={{
                flex: "1",
                borderRadius: "40px",
                border: "1px solid #5ea1f7",
                padding: "15px",
                display: "flex",
                alignItems: "center",
                gap: "20px",
                height: "50px",
                boxSizing: "border-box",
              }}
            >
              <div style={{ borderRight: "1px solid #000", paddingRight: "20px" }}>
                <Select
                  value={value}
                  style={{ width: "20vw", maxWidth: "200px" }}
                  options={options}
                  onChange={handleChange}
                />
              </div>
              <div style={{ flex: "1" }}>
                <input
                  value={keyword || ""}
                  style={{ width: "100%", height: "30px", border: "none", outline: "none" }}
                  type="text"
                  placeholder="Enter any string of …"
                  onChange={(e) => setKeyword(e.target.value)}
                />
              </div>
            </div>
            <div
              style={{
                display: "flex",
                alignItems: "center",
                background: "linear-gradient(90deg, #0078f9, #56b8fb)",
                padding: "0 20px",
                gap: "5px",
                color: "#fff",
                borderRadius: "30px",
                marginLeft: "-60px",
                cursor: "pointer",
                height: "50px",
              }}
              onClick={() => {
                setSelectedRowKeys([]);
                setCurrent(1);
                getDataList("", 0, 1);
              }}
            >
              <img src={SearchPng} alt="" />
              <div className="searchText">Search</div>
            </div>
          </div>
        </div>
        <div style={{ marginTop: "20px" }}>
          <Table
            rowSelection={{ type: "checkbox", ...rowSelection }}
            ref={tableRef}
            loading={loading}
            dataSource={dataSource}
            scroll={{ x: "max-content" }}
            pagination={{
              current: current,
              pageSize: pageSize,
              total: total,
              onChange: handleChange1,
            }}
            onChange={sortChange}
          >
            {columns.map((item) => (
              <Table.Column
                title={item.title}
                dataIndex={item.dataIndex}
                key={item.key}
                width={item.width}
                fixed={(item?.fixed as any) || false}
                sorter={item?.sorter}
                showSorterTooltip={false}
              />
            ))}
            <Table.Column
              title="2D structure"
              dataIndex="id"
              key="id"
              width={200}
              render={(id) => {
                return <div onClick={() => showModel(id)} id={`2d-structure${id}`}></div>;
              }}
            />
          </Table>
        </div>
        <div
          style={{ display: "flex", alignItems: "center", gap: "20px", justifyContent: "flex-end", marginTop: "20px" }}
        >
          <div style={{ marginRight: "200px", fontSize: "13px" }}>
            If not otherwise specified in the Annotation column: uppercase letters denote ribonucleotides; lowercase
            letters denote deoxyribonucleotides; ‘...’ indicates bases not explicitly reported in the original
            publication; an underscore ‘_’ marks the cleavage site; a hyphen ‘-’ marks the ligation site; and
            double-stranded regions are separated by a slash ‘/’.
          </div>
          <Button size="large" type="primary" icon={<SaveOutlined />} onClick={exportFile}>
            Save Table
          </Button>
          <Button size="large" type="primary" icon={<SaveOutlined />} onClick={exportFile1}>
            Save Selected rows
          </Button>
        </div>
      </div>

      <Modal
        title="2D structure"
        closable={{ "aria-label": "Custom Close Button" }}
        open={open}
        onCancel={handleOk}
        footer={() => <div></div>}
      >
        <div id="cofold_ss"></div>
      </Modal>
    </div>
  );
}
